#include "command_factory.h"
#include <iostream>
#include <sstream>
CommandFactory::CommandFactory(Editor *editor,CommandHistory *history,std::string lexicon_dir){
  this->editor = editor;
  this->history = history;
  environ = new Environ();
  environ->lang = ENG;
  environ->format = TXT;
  StrategyFactory *sf = new StrategyFactory(environ,std::move(lexicon_dir));
  sc = new SpellChecker(sf);
}
CommandFactory::~CommandFactory(){
  delete environ;
  delete sc;
}
Command * 
CommandFactory::create_ACommand(Position pos,std::string content){
  std::string action;
  switch(pos){
    case HEAD:action = "a";break;
    case TAIL:action = "A";break;
    default:action = "a";
  }
  std::stringstream ss;
  ss << action << " \"" << content << "\"";
  return new ACommand(ss.str(),editor,pos,content);
}
Command * 
CommandFactory::create_DCommand(Position pos,int len){
  std::string action;
  switch(pos){
    case HEAD:action = "d";break;
    case TAIL:action = "D";break;
    default:action = "d";
  }
  std::stringstream ss;
  ss << action << " " << std::to_string(len);
  return new DCommand(ss.str(),editor,pos,len);
}
Command * 
CommandFactory::create_SCommand(){
  return new SCommand("s",editor);
}
Command * 
CommandFactory::create_LanCommand(std::string lang){
  Lang lan = ENG;
  if(lang == "fra")
    lan = FRA;
  else if(lang != "eng"){
    std::cerr << "Error:Unsupported Language "<< lang << std::endl;
    return NULL;
  }
  std::string action("lan ");
  return new LanCommand(action+lang,editor,environ,lan);
}
Command * 
CommandFactory::create_ContextCommand(std::string content){
  Format format = TXT;
  if(content == "xml")
    format = XML;
  else if(content != "txt"){
    std::cerr << "Error:Unsupported Format "<< content << std::endl;
    return NULL;
  }
  std::string action("content ");
  return new ContextCommand(action+content,editor,environ,format);
}
Command * 
CommandFactory::create_LCommand(int n){
  std::string action("l ");
  return new LCommand(action+std::to_string(n),editor,history,n);
}
Command * 
CommandFactory::create_UCommand(){
  return new UCommand("u",editor,history);
}
Command * 
CommandFactory::create_RCommand(){
  return new RCommand("r",editor,history);
}
Command * 
CommandFactory::create_MDCommand(int n,std::string cmd_name){
  std::string action("m ");
  action += n;
  action += " " + cmd_name;
  return new MDCommand(action,editor,history,cmd_name,environ,n);
}
Command * 
CommandFactory::create_MCommand(std::string cmd_name){
  std::string action("$");
  action += cmd_name;
  auto iter = environ->macros.find(cmd_name);
  if(iter == environ->macros.end()){
    std::cerr << "Error:Macro Command " << cmd_name << " has not been defined!"<< std::endl;
    return NULL;
  }
  return new MCommand(action,editor,iter->second);
}
Command * 
CommandFactory::create_SPCommand(){
  return new SPCommand("spell",editor,sc);
}
Command * 
CommandFactory::create_SPACommand(){
  return new SPACommand("spell-a",editor,sc);
}
Command * 
CommandFactory::create_SPMCommand(){
  return new SPMCommand("spell-m",editor,sc);
}
